package io.renren.modules.training.service.impl;

import io.renren.modules.generator.dao.TTrainingObjectDao;
import io.renren.modules.generator.entity.TTrainingObjectEntity;
import io.renren.modules.generator.entity.TTrainingScoreEntity;
import io.renren.modules.generator.entity.vo.TTrainingScoreVo;
import io.renren.modules.generator.service.TTrainingScoreService;
import io.renren.modules.training.entity.vo.TrainingScoreVo;
import io.renren.modules.training.service.TrainingManageService;
import io.renren.modules.training.util.PoiUtil;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service("trainingManageService")
public class TrainingManageServiceImpl implements TrainingManageService {
    @Resource
    private TTrainingObjectDao tTrainingObjectDao;
    @Resource
    private TTrainingScoreService tTrainingScoreService;


    public  Map<String, Object> getTrainingScoreInfo(Workbook workbook, Integer trainingId,Integer trainingCheckId) {
        Map<String, Object> result = new HashMap<String, Object>();
        List<TTrainingScoreVo>  trainingScoreVoList=new ArrayList<>();
        boolean tempResult = true;
        String message = "";
        try {
            Map<Integer, String> firstRowCellMap = PoiUtil.getFirstRowCells(workbook,"Recovered_Sheet1");
            Sheet sheet = workbook.getSheet("Recovered_Sheet1");
            int allRows = sheet.getPhysicalNumberOfRows();
            //判断导入模板内容是否为空
            if(allRows <= 1){
                tempResult = false;
                message = "表格数据为空";
                result.put("isValid", tempResult);
                result.put("list", trainingScoreVoList);
                result.put("message", message);
                return result;
            }
            List<TTrainingObjectEntity> objectList=tTrainingObjectDao.getObjectListByTrainingId(trainingId);
            HashMap<String,Integer> objectMap=new HashMap();
            for (TTrainingObjectEntity objectEntity: objectList) {
                objectMap.put(objectEntity.getObjectName(),objectEntity.getObjectId());
            }
            List<String> idNoList=new ArrayList<>();
            for(int i=2;i<allRows;i++){
                Row row = sheet.getRow(i);
                if(row == null || PoiUtil.isNullRow(row, row.getPhysicalNumberOfCells())){
                    continue;
                }
                Cell idNoCell = row.getCell(2);
                if(idNoCell == null || idNoCell.getCellType() == Cell.CELL_TYPE_BLANK){
                    tempResult = false;
                    message = "第[\"+(i)+\"]行缺少身份证号";
                    result.put("isValid", tempResult);
                    result.put("list", trainingScoreVoList);
                    result.put("message", message);
                    return result;
                }
                idNoList.add(idNoCell.getStringCellValue().trim());
            }
            List<Map<String,Object>> peopleIdInfoList=tTrainingScoreService.batchGetPeopleId(idNoList);

            for(int i=2;i<allRows;i++){
                //获取excel第i行记录
                Row row = sheet.getRow(i);
                if(row == null || PoiUtil.isNullRow(row, row.getPhysicalNumberOfCells())){
                    continue;
                }
                TTrainingScoreVo tTrainingScoreVo=new TTrainingScoreVo();
                TreeMap<Object, Object> treeMap = new TreeMap<Object, Object>();

                //获取第i行记录的题目类型  excel中所有试题类型都为必选项
                Cell idNoCell = row.getCell(2);
                if(idNoCell == null || idNoCell.getCellType() == Cell.CELL_TYPE_BLANK){
                    tempResult = false;
                    message = "第["+(i)+"]行缺少身份证号";
                    break;
                }
                //获取每行的单元格数量
                int cellNumber = firstRowCellMap.size();
                Integer peopleId=getPeoPleIdByIdNo(idNoCell.getStringCellValue().trim(),peopleIdInfoList);
                for(int j = 3; j < cellNumber; j++){
                    String objectName=firstRowCellMap.get(j);
                    Integer trainingObjectId=objectMap.get(objectName);
                    tTrainingScoreVo.setTrainingObjectId(trainingObjectId);
                    tTrainingScoreVo.setTrainingCheckId(trainingCheckId);
                    tTrainingScoreVo.setTrainingId(trainingId);
                    tTrainingScoreVo.setTrainingPeopleId(peopleId);
                    Cell cell = row.getCell(j);
                    cell.setCellType(Cell.CELL_TYPE_STRING);
                    String score = cell.getStringCellValue().trim();
                    if(StringUtils.isEmpty(score)){
                        tempResult = false;
                        message = "第["+(i)+"]"+objectName+"项目分数为空";
                        break;
                    }
                    tTrainingScoreVo.setScore(score);
                    trainingScoreVoList.add(tTrainingScoreVo);
                }
            }


        } catch (Exception e) {
            tempResult = false;
            message = "导入模板格式错误";
            e.printStackTrace();
        }
        result.put("isValid", tempResult);
        result.put("list", trainingScoreVoList);
        result.put("message", message);
        return result;
    }

    public Integer getPeoPleIdByIdNo(String idNo,List<Map<String,Object>> peopleIdInfoList){
        if(CollectionUtils.isEmpty(peopleIdInfoList)){
            return null;
        }
        List<Map<String,Object>> filiteResult=peopleIdInfoList.stream().filter(s->s.get("idcard").equals(idNo)).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(filiteResult)){
            return null;
        }
        Map<String ,Object> map=filiteResult.get(0);
        Integer peopleId=(Integer)map.get("id") ;
        return peopleId;
    }

    public Boolean createExcel(FileOutputStream os, List<TTrainingScoreEntity> scoreEntityList){
        Boolean flag=true;
        try {
            if(CollectionUtils.isEmpty(scoreEntityList)){
                return false;
            }


            scoreEntityList=scoreEntityList.stream().filter(x->x.getIdcard()!=null).collect(Collectors.toList());
            Map<String, List<TTrainingScoreEntity>> groupByIdCard =
                    scoreEntityList.stream().collect(Collectors.groupingBy(TTrainingScoreEntity::getIdcard));

            List<TTrainingObjectEntity> objectList=tTrainingObjectDao.getObjectListByTrainingId(scoreEntityList.get(0).getTrainingId());
            List<String> title=new ArrayList<>();
            title.add("人员");
            title.add("身份证号");

            HashMap<Integer,Integer> objectIndexMap=new HashMap();
            for(int i=0;i<objectList.size();i++){
                title.add(objectList.get(i).getObjectName());
                objectIndexMap.put(objectList.get(i).getObjectId(),i+2);
            }

            // 第一步，创建一个webbook，对应一个Excel文件
            HSSFWorkbook wb = new HSSFWorkbook();
            // 第二步，在webbook中添加一个sheet,对应Excel文件中的sheet
            HSSFSheet sheet = wb.createSheet("成绩表");
            sheet.setDefaultColumnWidth(20);// 默认列宽
            // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
            HSSFRow row = sheet.createRow(0);
            // 第四步，创建单元格，并设置值表头 设置表头居中
            HSSFCellStyle style = wb.createCellStyle();
            // 创建一个居中格式
            style.setAlignment(HSSFCellStyle.ALIGN_CENTER);

            // 添加excel title
            HSSFCell cell = null;
            for (int i = 0; i < title.size(); i++) {
                cell = row.createCell((short) i);
                cell.setCellValue(title.get(i));
                cell.setCellStyle(style);
            }

            // 第五步，写入实体数据 ,list中字符串的顺序必须和数组strArray中的顺序一致
            int i = 0;
            for (String str : groupByIdCard.keySet()) {
                row = sheet.createRow(i + 1);
                List<TTrainingScoreEntity> list = groupByIdCard.get(str);

                // 第六步，创建单元格
                for (int j = 0; j < title.size(); j++) {
                    if(j==0){
                        row.createCell((short) j).setCellValue(list.get(0).getName());
                    }else if(j==1){
                        row.createCell((short) j).setCellValue(list.get(0).getIdcard());
                    }else {
                        row.createCell((short) j);
                    }

                }
                //第七步，给对应的单元格设置分数


                for (TTrainingScoreEntity tTrainingScoreEntity:list) {
                    Integer index=objectIndexMap.get(tTrainingScoreEntity.getTrainingObjectId());
                    if(index!=null){
                        String currentMark=row.getCell(index).getStringCellValue();
                        Boolean needReplace=true;
                        if(StringUtils.isNotEmpty(currentMark)&& StringUtils.isNotEmpty(tTrainingScoreEntity.getMark())){
                            Double current=Double.parseDouble(currentMark);
                            Double newMark=Double.parseDouble(tTrainingScoreEntity.getMark());
                            if(current>newMark){
                                needReplace=false;
                            }

                        }
                        if(needReplace){
                            row.getCell(index).setCellValue(tTrainingScoreEntity.getMark());
                        }
                    }


                }
                i++;
            }

            // 第八步，将文件存到指定输出流
            try {
                wb.write(os);
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                os.close();
            }
        } catch (Exception e) {
            flag=false;
            e.printStackTrace();
        }

        return flag;
    }

    public List<List<String>> getTraingScoreData( List<TTrainingScoreEntity> scoreEntityList) {
        List<List<String>> scoreData = new ArrayList<>();
        Boolean flag = true;
        if (CollectionUtils.isEmpty(scoreEntityList)) {
            return null;
        }
        scoreEntityList=scoreEntityList.stream().filter(x->x.getIdcard()!=null).collect(Collectors.toList());
        Map<String, List<TTrainingScoreEntity>> groupByIdCard =
                scoreEntityList.stream().collect(Collectors.groupingBy(TTrainingScoreEntity::getIdcard));

        List<TTrainingObjectEntity> objectList = tTrainingObjectDao.getObjectListByTrainingId(scoreEntityList.get(0).getTrainingId());
        List<String> title = new ArrayList<>();
        title.add("人员");
        title.add("身份证号");

        HashMap<Integer, Integer> objectIndexMap = new HashMap();
        for (int i = 0; i < objectList.size(); i++) {
            title.add(objectList.get(i).getObjectName());
            objectIndexMap.put(objectList.get(i).getObjectId(), i + 2);
        }
        List<String> titleList = new ArrayList<>(title.size());

        // 创建一个居中格式

        // 添加excel title
        for (int i = 0; i < title.size(); i++) {
            titleList.add(i, title.get(i));
        }
        scoreData.add(titleList);

        // 第五步，写入实体数据 ,list中字符串的顺序必须和数组strArray中的顺序一致
        for (String str : groupByIdCard.keySet()) {
            List<String> rowList = new ArrayList<>(title.size());
            List<TTrainingScoreEntity> list = groupByIdCard.get(str);
            // 第六步，创建单元格
            for (int j = 0; j < title.size(); j++) {
                if (j == 0) {
                    rowList.add(j, list.get(0).getName());
                } else if (j == 1) {
                    rowList.add(j, list.get(0).getIdcard());
                }else {
                    rowList.add(j,"");
                }

            }
            //第七步，给对应的单元格设置分数


            for (TTrainingScoreEntity tTrainingScoreEntity : list) {
                Integer index = objectIndexMap.get(tTrainingScoreEntity.getTrainingObjectId());
                if (index != null) {
                    String currentMark = rowList.get(index);
                    Boolean needReplace = true;
                    if (StringUtils.isNotEmpty(currentMark) && StringUtils.isNotEmpty(tTrainingScoreEntity.getMark())) {
                        Double current = Double.parseDouble(currentMark);
                        Double newMark = Double.parseDouble(tTrainingScoreEntity.getMark());
                        if (current > newMark) {
                            needReplace = false;
                        }

                    }
                    if (needReplace) {
                        rowList.set(index, tTrainingScoreEntity.getMark());
                    }
                }


            }
            scoreData.add(rowList);
        }

        return scoreData;
    }
}
